<?php
    /*

     Version: MPL 1.1

     Software distributed under the License is distributed on an "AS IS"
     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
     License for the specific language governing rights and limitations
     under the License.

     The Original Code is KASSIOP Framework.

     The Initial Developer of the Original Code is SURIAN Nicolas (aka NairuS) <me@nairus.fr>.
     Portions created by the Initial Developer are Copyright (C) 2010
     The Initial Developer. All Rights Reserved.

     Contributor(s):

     Alternatively, the contents of this file may be used under the terms
     of the MPL license Version 1.1 (the  "MPL" License"), in which case the
     provisions of Version: MPL 1.1 License are applicable instead of those
     above.  If you wish to allow use of your version of this file only
     under the terms of the MPL License and not to allow others to use
     your version of this file under the MPL, indicate your decision by
     deleting  the provisions above and replace  them with the notice and
     other provisions required by the MPL License.  If you do not delete
     the provisions above, a recipient may use your version of this file
     under either the MPL License.

     The contents of this file are subject to the Mozilla Public License
     Version 1.1 (the "License"); you may not use this file except in
     compliance with the License. You may obtain a copy of the License at
     http://www.mozilla.org/MPL/

    */

    /**
     * Manages the credentials of the application
     *
     * @package    kassiop
     * @subpackage managers
     *
     * @author NairuS
     * @version 1.2 $Rev: 90 $ $Date: 2011-01-16 09:23:26 +0000 (Sun, 16 Jan 2011) $ $Author: nicolas.surian $
     */
    abstract class CredentialsManager
    {
        /**
         * Creates an instance of CredentialsManager.
         *
         * @param string $credentials the file's path of the credentials to load.
         * @return void
         */
        public function __construct( $credentials = null )
        {
            // load the credentials from the external file passed-in.
            if( is_file( $credentials ) )
            {
                try
                {
                    // try to open the credentials file in read only.
                    $handle = fopen( $credentials , "r" ) ;

                    // browse the line of the file to set the cretentials.
                    while( !feof( $handle ) )
                    {
                        $row                     = fgets( $handle , 4096 ) ;
                        $aRow                    = explode( '=' , trim( $row ) ) ;
                        $key                     = trim( $aRow[0] ) ;
                        $value                   = trim( $aRow[1] ) ;
                        $this->credentials[$key] = $value ;
                    }
                    fclose( $handle ) ;
                }
                catch( Exception $e )
                {
                    throw new Exception( "The credentials file doesn't exist!" ) ;
                }
            }

            // launch the custom setUp method.
            $this->setUp() ;
        }

        /**
         * Defines the credentials of the application.
         *
         * @var array
         */
        protected $credentials = array() ;

        /**
         * Defines the roles of the application.
         *
         * @var array
         */
        protected $roles = array() ;

        /**
         * Configures the credentials for the application.
         *
         * @param  array $credentials
         * @param  array $roles
         * @return void
         */
        public function configure( array $credentials = array(), array $roles = array() )
        {
            // erases the identical credentials setted before in the credentials properties if they exist in the $credentials array passed-in.
            $this->credentials = array_merge( $this->credentials, $credentials ) ;
            $this->roles       = $roles ;
        }

        /**
         * Returns the credential passed-in.
         *
         * @param  string $credential
         * @return string
         */
        public function getCredential( $credential )
        {
            // Return the credential if it's defined or seek the parent.
            if( isset( $this->credentials[$credential] ) )
            {
                return $this->credentials[$credential] ;
            }
            else
            {
                $pos = strpos( $credential, '.' );

                // If we found the separator of the credential, we seek the parent.
                if( $pos !== false )
                {
                    $parent = substr( $credential, 0, $pos );
                    return isset( $this->credentials[$parent] ) ? $this->credentials[$parent] : null ;
                }
                return null ;
            }
        }

        /**
         * Returns all the credentials defined in the class.
         *
         * @return array
         */
        public function getCredentials()
        {
            return $this->credentials ;
        }

        /**
         * Return the RoleVO for the slug passed-in
         *
         * @param  string $slug
         * @return RoleVO
         */
        public function getRole( $slug )
        {
            foreach( $this->getRoles() as $role )
            {
                if( $role instanceof RoleVO && $role->slug == $slug )
                {
                    return $role ;
                }
            }
            return null ;
        }

        /**
         * Returns all the roles defined in the class.
         *
         * @return array
         */
        public function getRoles()
        {
            return $this->roles ;
        }

        /**
         * Returns true if there is a credential for a view or an action and if the role has the rigth to use it.
         *
         * @param string $credential
         * @param RoleVO $userRole
         * @return boolean
         */
        public function hasCredential( $credential, RoleVO $userRole = null )
        {
            $rights = $this->getCredential( $credential ) ;
            if( $rights === null )
            {
                return true ;
            }

            if( $userRole instanceof RoleVO )
            {
                // if the rights of the credential has many roles.
                $rightsStack = explode( ',', $rights ) ;
                if( count( $rightsStack ) > 1 )
                {
                    foreach( $rightsStack as $right )
                    {
                        $role = $this->getRole( $right ) ;
                        if( $this->getRole( $right ) instanceof RoleVO && $role->slug == $userRole->slug )
                        {
                            return true ;
                        }
                    }
                }
                else
                {
                    $role = $this->getRole( $rights ) ;
                    if( $role instanceof RoleVO && $role->rank <= $userRole->rank )
                    {
                        return true ;
                    }
                }
            }
            return false ;
        }

        /**
         * Sets the credentials of the application.
         * Method to override.
         *
         * @return void
         */
        public function setUp()
        {
        }
    }
?>